/* eslint-disable */

import axios from "axios";
import config from "@/config/index"; // 路径配置
import { getToken } from "@/utils/auth";
import "@/api/mock.js";
import { showFullScreenLoading, tryHideFullScreenLoading } from "./loading";

const CancelToken = axios.CancelToken;

const whiteList = ["/users"]; // 不需要loading的接口

let isRefreshing = false; // 标记是否正在刷新 token
let requests = []; // 存储待重发请求的数组

export const cancel = []; // 暴露给router文件,每次跳转就取消之前的请求

// 创建axios 实例
const service = axios.create({
	baseURL: config.baseURL, // BaseUrl
	timeout: 30000, // 请求超时时间 (包括查询和接收数据的时间)
	validateStatus: function (status) {
		return status >= 200 && status < 300; // 默认的  true 进入 resolve ，false 进入catch
	},
	headers: {},
});

// 刷新 access_token 的接口
const refreshToken = () => {
	return service.post("/auth/refresh", { refresh_token: getRefreshToken() }, true);
};

// request 拦截器
service.interceptors.request.use(
	config => {
		// config.url = config.url + (config.url.indexOf('?') > 0 ? '&' : '?') + `cb=${new Date().getTime()}`;

		// 在发送请求之前做些什么
		if (getToken()) {
			config.headers["Authorization"] = getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改
		}
		// 存储 取消请求cancelToken 可以根据请求参数，判断切换路由是否取消该请求,
		config.cancelToken = new CancelToken(function executor(c) {
			// console.log(c.routeChangeCancel = config.params?config.params.routeChangeCancel:true);
			cancel.push(c);
		});

		const res = whiteList.some(v => config.url.includes(v));

		!res && showFullScreenLoading(); // 不在白名单就显示loading
		return config;
	},
	error => {
		// 对请求错误做些什么
		tryHideFullScreenLoading();
		return Promise.reject(error); // 直接return error 会进入then ，这样写会进入catch
	}
);

// response 拦截器 失败和成功的回调都可以获取到请求信息，token过去，可以获取刷新token使用
service.interceptors.response.use(
	response => {
		// 对响应数据做点什么
		tryHideFullScreenLoading();
		if (response.status === 200) {
			// 这里处理一些response 正常放回时的逻辑
			return Promise.resolve(response.data);
		} else {
			return Promise.reject(response);
		}
	},
	error => {
		// 判断是否主动取消的请求
		// console.log(axios.isCancel(error));

		// 对响应错误做点什么
		tryHideFullScreenLoading();
		if (!error.response) {
			// 断网处理
			if (!window.navigator.onLine) {
				// 断开网络了，可以让其跳转到断网页面
				return;
			}
			return Promise.reject(error);
		}
		if (error.response.status === 401 && !error.config.url.includes("/auth/refresh")) {
			const { config } = error;
			if (!isRefreshing) {
				isRefreshing = true;
				return refreshToken()
					.then(res => {
						const { access_token } = res.data;
						setToken(access_token);
						config.headers.Authorization = `Bearer ${access_token}`;
						// token 刷新后将数组的方法重新执行
						requests.forEach(cb => cb(access_token));
						requests = []; // 重新请求完清空
						return service(config);
					})
					.catch(err => {
						console.log("抱歉，您的登录状态已失效，请重新登录！");
						return Promise.reject(err);
					})
					.finally(() => {
						isRefreshing = false;
					});
			} else {
				return new Promise(resolve => {
					// 这里先加入队列，等上面的刷新token完毕，会调用这里的函数 // requests.forEach((cb) => cb(access_token));
					requests.push(token => {
						config.headers.Authorization = `Bearer ${token}`;
						resolve(service(config));
					});
				});
			}
		}
		return Promise.reject(error);
	}
);

export default service;
